package com.dzl.util;

import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.Date;
import java.util.Hashtable;
import java.util.Map;

import javax.imageio.ImageIO;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import com.dzl.aliyunoss.ALiYunOSSConstant;
import com.dzl.aliyunoss.ALiYunOSSUtis;
import com.dzl.util.wx.WxConfig;
import com.google.zxing.*;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.caucho.hessian.client.HessianProxyFactory;
import com.dzl.constant.UploadConstant;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.yome.upload.service.FileUploadService;

public class QRCode {

	private static final Logger logger = LoggerFactory.getLogger(QRCode.class);

	private static final int BLACK = 0xff000000;
	private static final int WHITE = 0xFFFFFFFF;

	/**
	 *  生成QRCode二维码<br>
	 *  在编码时需要将com.google.zxing.qrcode.encoder.Encoder.java中的<br>
	 *  static final String DEFAULT_BYTE_MODE_ENCODING = "ISO8859-1";<br>
	 *  修改为UTF-8，否则中文编译后解析不了<br>
	 * @param contents 二维码的内容
	 * @param file 二维码保存的路径，如：C://test_QR_CODE.png
	 * @param filePostfix 生成二维码图片的格式：png,jpeg,gif等格式
	 * @param format qrcode码的生成格式
	 * @param width 图片宽度
	 * @param height 图片高度
	 * @param hints
	 */
	public void encode(String contents, File file,String filePostfix, BarcodeFormat format, int width, int height, Map<EncodeHintType, ?> hints) {
		try {
			//创建HessianProxyFactory实例
	        HessianProxyFactory factory = new HessianProxyFactory();
	        factory.setOverloadEnabled(true);
	        //获得Hessian服务的远程引用
	        FileUploadService uploader = (FileUploadService) factory.create(FileUploadService.class,UploadConstant.UPLOAD_SERVICE);
	        //调用远程服务上传文件。
	        String UPL_DIR = UploadConstant.UPL_DIR+UploadConstant.IMAGE_URL_ORDER;
	        uploader.createOrderQrcode(contents, file, UPL_DIR, filePostfix, format, width, height, hints);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 生成二维码图片<br>
	 * @param matrix
	 * @param format 图片格式
	 * @param file 生成二维码图片位置
	 * @throws IOException
	 */
	public static void writeToFile(BitMatrix matrix, String format, File file) throws IOException {
		BufferedImage image = toBufferedImage(matrix);
		ImageIO.write(image, format, file);
	}

	/**
	 * 生成二维码内容<br>
	 * @param matrix
	 * @return
	 */
	public static BufferedImage toBufferedImage(BitMatrix matrix) {
		int width = matrix.getWidth();
		int height = matrix.getHeight();
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
		for (int x = 0; x < width; x++) {
			for (int y = 0; y < height; y++) {
				image.setRGB(x, y, matrix.get(x, y) == true ? BLACK : WHITE);
			}
		}
		return image;
	}

	/**
	 * 解析QRCode二维码
	 */
	@SuppressWarnings("unchecked")
	public void decode(File file) {
		try {
			BufferedImage image;
			//try {
				image = ImageIO.read(file);
				if (image == null) {
					logger.info("不能解码图像");
				}
				LuminanceSource source = new BufferedImageLuminanceSource(image);
				BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
				Result result;
				@SuppressWarnings("rawtypes")
				Hashtable hints = new Hashtable();
				//解码设置编码方式为：utf-8
				hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
				result = new MultiFormatReader().decode(bitmap, hints);
				String resultStr = result.getText();
				logger.info("解析后内容：" + resultStr);
			/*} catch (IOException ioe) {
				logger.info("解析QRCode二维码io异常："+ioe.getMessage());
				System.out.println(ioe.toString());
			} catch (ReaderException re) {
				logger.info("解析QRCode二维码re异常："+re.getMessage());
			}*/
		} catch (Exception ex) {
			logger.info("解析QRCode二维码异常："+ex.getMessage());
			ex.printStackTrace();
		}
	}

	/**
	 *
	 * @Description:订单编号二维码-扫码枪使用
	 * @param orderNo
	 * @return
	 * String
	 * @exception:
	 * @author: liufan
	 * @time:2020年8月17日 上午10:46:08
	 */
	public static String getOrderNoQrCode(String orderNo) {
		String filePath = UploadConstant.IMAGE_URL_ORDER + orderNo + ".png";
		try {
			BufferedImage bufferedImage = null;
			try {
				bufferedImage = createImage(filePath);
			} catch (Exception ex) {
				ex.getMessage();
			} finally {
				if (bufferedImage != null) {
					bufferedImage.getGraphics().dispose();
				}
			}
			//BufferedImage 转换为 InputStream
			InputStream inputStream = bufferedImageToInputStream(bufferedImage);
			//上传图片到阿里云
			OSS ossClient=new OSSClientBuilder().build(ALiYunOSSConstant.OSS_ENDPOINT, ALiYunOSSConstant.OSS_ACCESS_KEY_ID,ALiYunOSSConstant.OSS_ACCESS_KEY_SECRET);
			// 创建PutObjectRequest对象。
			PutObjectRequest putObjectRequest = new PutObjectRequest(ALiYunOSSConstant.BUCKET_NAME, filePath, inputStream);
			// 上传
			ossClient.putObject(putObjectRequest);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("生成二维码出错!");
		}
		return ALiYunOSSConstant.FILE_LOCATION+filePath;
	}

	/**
	 * 生成二维码
	 * @date 2021/09/14 14:09
	 * @author liufan
	 * @param url 二维码链接
	 * @return java.awt.image.BufferedImage
	 */
	public static BufferedImage createImage(String url){
		Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
		hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
		hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
		hints.put(EncodeHintType.MARGIN, 1);
		BitMatrix bitMatrix = null;
		try {
			bitMatrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, 400, 400,hints);
		}catch (Exception e){
			e.printStackTrace();
		}
		int width = bitMatrix.getWidth();
		int height = bitMatrix.getHeight();
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

		for (int x = 0; x < width; x++) {
			for (int y = 0; y < height; y++) {
				image.setRGB(x, y, bitMatrix.get(x, y) ? BLACK : WHITE);
			}
		}
		return image;
	}
	/**
	 * 将BufferedImage转换为InputStream
	 * @param image
	 * @return
	 */
	public static InputStream bufferedImageToInputStream(BufferedImage image) {
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		try {
			ImageIO.write(image, "png", os);
			InputStream input = new ByteArrayInputStream(os.toByteArray());
			return input;
		} catch (IOException e) {
		}
		return null;
	}

	/**
	 * @Description:电影订单二维码
	 * @param ticketcode 取票码
	 * @author: liuguanjun
	 * @time:2020年11月06日 15:20:08
	 */
	public static String getMovieOrderTicketQrCode(String ticketcode) {
		String filePath = ALiYunOSSConstant.QRCODE_IMG_CENTRE + DateUtil.getDateTimeSequence()+StringUtil.getRandomStringHasOnlyNumber(6) + ".png";
		try {
			BufferedImage bufferedImage = null;
			try {
				bufferedImage = createImage(ticketcode);
			} catch (Exception ex) {
				ex.getMessage();
			} finally {
				if (bufferedImage != null) {
					bufferedImage.getGraphics().dispose();
				}
			}
			//BufferedImage 转换为 InputStream
			InputStream inputStream = bufferedImageToInputStream(bufferedImage);
			//上传图片到阿里云
			OSS ossClient=new OSSClientBuilder().build(ALiYunOSSConstant.OSS_ENDPOINT, ALiYunOSSConstant.OSS_ACCESS_KEY_ID,ALiYunOSSConstant.OSS_ACCESS_KEY_SECRET);
			// 创建PutObjectRequest对象。
			PutObjectRequest putObjectRequest = new PutObjectRequest(ALiYunOSSConstant.BUCKET_NAME, filePath, inputStream);
			// 上传
			ossClient.putObject(putObjectRequest);
			//二维码存参数
			/*QRCodeWriter qrCodeWriter = new QRCodeWriter();
			BitMatrix bitMatrix = qrCodeWriter.encode(ticketcode, BarcodeFormat.QR_CODE, 200, 200);
			Path path = FileSystems.getDefault().getPath(filePath);
			MatrixToImageWriter.writeToPath(bitMatrix, "PNG", path);*/
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("生成二维码出错!");
		}
		return ALiYunOSSConstant.FILE_LOCATION+filePath;
	}

	/**
	 * @Description:卡密二维码
	 * @param  secret 卡密
	 * @author: liuguanjun
	 * @time:2020年11月06日 15:20:08
	 */
	public static String getCardSecretQrCode(String secret) {
		String filePath = ALiYunOSSConstant.QRCODE_IMG_CENTRE + DateUtil.getDateTimeSequence()+StringUtil.getRandomStringHasOnlyNumber(6) + ".png";
		try {
			BufferedImage bufferedImage = null;
			try {
				//二维码存参数
				bufferedImage = createImage(secret);
			} catch (Exception ex) {
				ex.getMessage();
			} finally {
				if (bufferedImage != null) {
					bufferedImage.getGraphics().dispose();
				}
			}
			//BufferedImage 转换为 InputStream
			InputStream inputStream = bufferedImageToInputStream(bufferedImage);
			//上传图片到阿里云
			OSS ossClient=new OSSClientBuilder().build(ALiYunOSSConstant.OSS_ENDPOINT, ALiYunOSSConstant.OSS_ACCESS_KEY_ID,ALiYunOSSConstant.OSS_ACCESS_KEY_SECRET);
			// 创建PutObjectRequest对象。
			PutObjectRequest putObjectRequest = new PutObjectRequest(ALiYunOSSConstant.BUCKET_NAME, filePath, inputStream);
			// 上传
			ossClient.putObject(putObjectRequest);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("生成二维码出错!");
		}
		return ALiYunOSSConstant.FILE_LOCATION+filePath;
	}


	public static void main(String[] args) {
		//String a = getCardSecretQrCode("K21000001");
		//System.out.println(a);

		String secretHasLine = "K21000001";
		//去掉最后一个“-”
		secretHasLine = secretHasLine.substring(0, secretHasLine.length() - 1);
		String qrcode = QRCode.getCardSecretQrCode(secretHasLine);
		System.out.println(qrcode);

		//String qrcode = ImageUtils.getWxCode("VZKBU802JX67NBLC", WxConfig.WX_XCX_APPID,WxConfig.WX_XCX_SECRET,"pages/home/index");
		//System.out.println(qrcode);
	}
}
